/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.purpose.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.koron.audit.approval.AfterApprovalService;
import com.koron.audit.domain.Audit;
import com.koron.audit.management.FlowManagement;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.purpose.bean.SuggestAdviceBean;
import com.koron.purpose.mapper.SuggestAdviceMapper;
import com.koron.purpose.service.api.SuggestAdviceService;
import com.koron.purpose.utils.BusinessCode;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.*;

@SuppressWarnings("deprecation")
@Service
public class SuggestAdviceServiceImpl implements SuggestAdviceService, AfterApprovalService, InitializingBean {

    private final Logger logger = LoggerFactory.getLogger(SuggestAdviceServiceImpl.class);
    // 建言建议状态：01-草稿
    private final String SUGGEST_ADVICE_STATUS_01 = "01";
    // 建言建议状态：02-审批中
    private final String SUGGEST_ADVICE_STATUS_02 = "02";
    // 建言建议状态：03-已采纳
    private final String SUGGEST_ADVICE_STATUS_03 = "03";
    // 建言建议状态：04-未采纳
    private final String SUGGEST_ADVICE_STATUS_04 = "04";

    @Value("${SuggAdvice_template_key}")
    private String templateKey;

    @Autowired
    private FlowManagement flowManagement;

    @Override
    public MessageBean<DataBean<Map>> queryForList(String corpCode, String suggestCompanyName, String suggestStatus,
                                                   String suggestTimeStart, String suggestTimeStop,
                                                   Integer page, Integer pageSize) {
        MessageBean<DataBean<Map>> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
            // 查询
            Map map = new HashMap();
            map.put("corpCode", corpCode);
            map.put("suggestCompanyName", suggestCompanyName);
            map.put("suggestStatus", suggestStatus);
            map.put("suggestTimeStart", suggestTimeStart);
            map.put("suggestTimeStop", suggestTimeStop);
            page = (page == null || page < 1) ? 1 : page;
            pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;
            int pageStart = (page - 1) * pageSize;
            map.put("pageStart", pageStart);
            map.put("pageStop", pageSize);
            List<Map> list = mapper.queryForList(map);
            DataBean<Map> dataBean = new DataBean<>();
            dataBean.setList(list);
            dataBean.setPageSize(pageSize);
            dataBean.setPageNo(page);
            // 总条数
            Integer totalNumber = mapper.countForList(map);
            int num = totalNumber / pageSize;
            // 总页数
            Integer totalPage = totalNumber % pageSize == 0 ? num : num + 1;
            dataBean.setTotalNumber(totalNumber);
            dataBean.setTotalPage(totalPage);
            msg.setData(dataBean);
            msg.setCode(BusinessCode.SUCCESS.getCode());
            msg.setDescription(BusinessCode.SUCCESS.getDescription());
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean<SuggestAdviceBean> queryById(String id) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        if (StringUtils.isEmpty(id)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        try (SessionFactory factory = new SessionFactory()) {
            SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
            SuggestAdviceBean bean = mapper.queryById(id);
            if (bean == null) {
                msg.setCode(BusinessCode.EXCEPTION.getCode());
                msg.setDescription("未查到该建言建议");
            } else {
                msg.setData(bean);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean deleteSuggestAdviceById(String id) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        if (StringUtils.isEmpty(id)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        SessionFactory factory = new SessionFactory();
        try {
            SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
            SuggestAdviceBean bean = mapper.queryById(id);
            if (bean == null) {
                msg.setCode(BusinessCode.EXCEPTION.getCode());
                msg.setDescription("该建言建议已被删除");
                factory.close(false);
                return msg;
            } else if (!SUGGEST_ADVICE_STATUS_01.equals(bean.getSuggestStatus())) {// 草稿可删除和编辑，非草稿不可删除和编辑
                msg.setCode(BusinessCode.EXCEPTION.getCode());
                msg.setDescription("当前建言建议不为草稿，不能进行删除");
                factory.close(false);
                return msg;
            }
            int i = mapper.deleteSuggestAdviceById(id);
            if (i != 1) {
                msg.setCode(BusinessCode.EXCEPTION.getCode());
                msg.setDescription("删除失败!");
                factory.close(false);
            } else {
                factory.close();
            }
        } catch (Exception e) {
            factory.close(false);
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean insertSuggestAdvice(StaffBean user, SuggestAdviceBean bean, String personCode) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        if (StringUtils.isEmpty(bean.getSuggestTitle()) || StringUtils.isEmpty(bean.getSuggestContent())
                || StringUtils.isEmpty(bean.getSuggestPerson()) || StringUtils.isEmpty(bean.getSuggestPersonName())
                || StringUtils.isEmpty(bean.getSuggestCompany()) || StringUtils.isEmpty(bean.getSuggestCompanyName())
                || StringUtils.isEmpty(bean.getCorpCode()) || StringUtils.isEmpty(bean.getCorpName())
                || StringUtils.isEmpty(bean.getSuggestStatus())) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        SessionFactory factory = new SessionFactory();
        try {
            SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
            bean.setId(DefaultIdGenerator.getInstance().generateLongId());
            bean.setSuggestTime(new Date());
            if (!SUGGEST_ADVICE_STATUS_02.equals(bean.getSuggestStatus())
                    && !SUGGEST_ADVICE_STATUS_04.equals(bean.getSuggestStatus())) {
                bean.setSuggestStatus(SUGGEST_ADVICE_STATUS_01);
            } else {
                bean.setSuggestStatus(SUGGEST_ADVICE_STATUS_04);
            }
            mapper.insertSuggestAdvice(bean);
            if (SUGGEST_ADVICE_STATUS_04.equals(bean.getSuggestStatus())) {
                if (StringUtils.isEmpty(personCode)) {
                    factory.close(false);
                    msg.setCode(BusinessCode.EXCEPTION.getCode());
                    msg.setDescription("审批人不能为空!");
                    return msg;
                }
                Audit audit = new Audit("建言建议", "建言建议审批", user.getName(), new Date());
                audit.setTitle("建言建议");
                audit.setDescription("建言建议审批");
                audit.setCorpCode(bean.getCorpCode());
                audit.setCorpName(bean.getCorpName());

                audit.setId(DefaultIdGenerator.getInstance().generateLongId());
                audit.setInitiatorCode(user.getCode());
                audit.setTarget(this.getClass().getName());
                audit.setTemplateKey(templateKey);
                audit.setSetCode("target_duty");
                audit.setInitiatorAccount(user.getUserid());
                audit.setOperation(1);
                audit.setState(1);
                audit.setFlowType(1);
                audit.setFlowName("建言建议审批");
                List<String> idList = Arrays.asList(bean.getId());
                audit.setBusinessIds(new Gson().toJson(idList));
                Map map = new HashMap();
                map.put("personCode", personCode);
                if (!flowManagement.initFlow(user, audit, map)) {
                    factory.close(false);
                    msg.setCode(com.koron.hazardsource.util.BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
                    msg.setDescription(com.koron.hazardsource.util.BusinessCode.MESSAGE_DESCRIPTION_FLOW_EXCEPTION);
                    return msg;
                }
            }
            factory.close();
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean updateSuggestAdvice(StaffBean user, SuggestAdviceBean bean, String personCode) {
        MessageBean msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), void.class);
        if (StringUtils.isEmpty(bean.getId()) || StringUtils.isEmpty(bean.getSuggestTitle())
                || StringUtils.isEmpty(bean.getSuggestContent())) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        SessionFactory factory = new SessionFactory();
        try {
            SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
            SuggestAdviceBean suggestAdviceBean = mapper.queryById(bean.getId());
            if (suggestAdviceBean == null) {
                msg.setCode(BusinessCode.EXCEPTION.getCode());
                msg.setDescription("该建言建议已被删除");
                factory.close(false);
                return msg;
            } else if (!SUGGEST_ADVICE_STATUS_01.equals(suggestAdviceBean.getSuggestStatus())) {// 草稿可删除和编辑，非草稿不可删除和编辑
                msg.setCode(BusinessCode.EXCEPTION.getCode());
                msg.setDescription("当前建言建议不为草稿，不能进行编辑");
                factory.close(false);
                return msg;
            }
            if (!SUGGEST_ADVICE_STATUS_02.equals(bean.getSuggestStatus())
                    && !SUGGEST_ADVICE_STATUS_04.equals(bean.getSuggestStatus())) {
                bean.setSuggestStatus(SUGGEST_ADVICE_STATUS_01);
            } else {
                bean.setSuggestStatus(SUGGEST_ADVICE_STATUS_04);
            }
            int i = mapper.updateSuggestAdvice(bean);
            if (i != 1) {
                msg.setCode(BusinessCode.EXCEPTION.getCode());
                msg.setDescription("修改失败!");
                factory.close(false);
            } else {
                if (SUGGEST_ADVICE_STATUS_04.equals(bean.getSuggestStatus())) {
                    if (StringUtils.isEmpty(personCode)) {
                        factory.close(false);
                        msg.setCode(BusinessCode.EXCEPTION.getCode());
                        msg.setDescription("审批人不能为空!");
                        return msg;
                    }
                    Audit audit = new Audit("建言建议", "建言建议审批", user.getName(), new Date());
                    audit.setTitle("建言建议");
                    audit.setDescription("建言建议审批");
                    audit.setCorpCode(bean.getCorpCode());
                    audit.setCorpName(bean.getCorpName());

                    audit.setId(DefaultIdGenerator.getInstance().generateLongId());
                    audit.setInitiatorCode(user.getCode());
                    audit.setTarget(this.getClass().getName());
                    audit.setTemplateKey(templateKey);
                    audit.setSetCode("target_duty");
                    audit.setInitiatorAccount(user.getUserid());
                    audit.setOperation(1);
                    audit.setState(1);
                    audit.setFlowType(1);
                    audit.setFlowName("建言建议审批");
                    List<String> idList = Arrays.asList(bean.getId());
                    audit.setBusinessIds(new Gson().toJson(idList));
                    Map map = new HashMap();
                    map.put("personCode", personCode);
                    if (!flowManagement.initFlow(user, audit, map)) {
                        factory.close(false);
                        msg.setCode(com.koron.hazardsource.util.BusinessCode.MESSAGE_CODE_FLOW_EXCEPTION);
                        msg.setDescription(com.koron.hazardsource.util.BusinessCode.MESSAGE_DESCRIPTION_FLOW_EXCEPTION);
                        return msg;
                    }
                }
                factory.close();
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
        }
        return msg;
    }

    @Override
    public List<Map> exportList(StaffBean user, String corpCode, String suggestCompanyName, String suggestStatus, String suggestTimeStart, String suggestTimeStop) {
        try (SessionFactory factory = new SessionFactory()) {
            SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
            // 查询
            Map map = new HashMap();
            map.put("corpCode", corpCode);
            map.put("suggestCompanyName", suggestCompanyName);
            map.put("suggestStatus", suggestStatus);
            map.put("suggestTimeStart", suggestTimeStart);
            map.put("suggestTimeStop", suggestTimeStop);
            map.put("pageStart", null);
            map.put("pageStop", null);
            List<Map> list = mapper.queryForList(map);
            return list;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return null;
        }
    }

    @Override
    public void editApproval(Audit audit) {
        Optional.ofNullable(audit)
                .map(obj -> obj.getBusinessIds())
                .map(ids -> {
                    List<String> list = JSON.parseArray(ids, String.class);
                    return Optional.ofNullable(list);
                }).map(idsList -> {
            List<String> idList = idsList.get();
            Optional.ofNullable(idList).map(ids -> {
                SessionFactory factory = new SessionFactory();
                try {
                    SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
                    for (String id : ids) {
                        // 根据 建议建议id修改  使用台账状态(01-草稿 02-审批中 03-已采纳 04-未采纳)
                        if (mapper.updateSugAdviceStatusById(id, SUGGEST_ADVICE_STATUS_03, audit.getCorpCode(), audit.getCorpName()) != 1) {
                            factory.close(false);
                            return null;
                        }
                    }
                    factory.close();
                } catch (Exception e) {
                    logger.error(e.getMessage(),e);
                    factory.close(false);
                }
                return null;
            });
            return null;
        });
    }

    @Override
    public void discardApproval(Audit audit) {

    }

    @Override
    public void processDiscard(Audit audit) {
        Optional.ofNullable(audit)
                .map(obj -> obj.getBusinessIds())
                .map(ids -> {
                    List<String> list = JSON.parseArray(ids, String.class);
                    return Optional.ofNullable(list);
                }).map(idsList -> {
            List<String> idList = idsList.get();
            Optional.ofNullable(idList).map(ids -> {
                SessionFactory factory = new SessionFactory();
                try {
                    SuggestAdviceMapper mapper = factory.getMapper(SuggestAdviceMapper.class);
                    for (String id : ids) {
                        // 根据 建议建议id修改  使用台账状态(01-草稿 02-审批中 03-已采纳 04-未采纳)
                        if (mapper.updateSugAdviceStatusById(id, SUGGEST_ADVICE_STATUS_01, null, null) != 1) {
                            factory.close(false);
                            return null;
                        }
                    }
                    factory.close();
                } catch (Exception e) {
                    logger.error(e.getMessage(),e);
                    factory.close(false);
                }
                return null;
            });
            return null;
        });
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        flowManagement.getHandlers().put(this.getClass().getName(), new SuggestAdviceServiceImpl());
    }

    @Override
    public void reject(Audit audit, List<String> userIdList) {
        // TODO 流程驳回操作
    }

    @Override
    public void passApproval(Integer operation, Audit audit) {
        // TODO 流程提交成功操作
    }
}
